package org.eiahe.hr.performance.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.ehe.common.core.BaseController;
import org.ehe.common.core.utils.MapstructUtils;
import org.eiahe.hr.performance.domain.PerformancePositionIndicator;
import org.eiahe.hr.performance.domain.PerformanceResult;
import org.eiahe.hr.performance.domain.PerformanceScoreDetail;
import org.eiahe.hr.performance.domain.bo.PerformanceResultBo;
import org.eiahe.hr.performance.domain.vo.PerformanceResultVo;
import org.eiahe.hr.performance.domain.vo.PerformanceScoreDetailVo;
import org.eiahe.hr.performance.mapper.PerformancePositionIndicatorMapper;
import org.eiahe.hr.performance.mapper.PerformanceResultMapper;
import org.eiahe.hr.performance.mapper.PerformanceScoreDetailMapper;
import org.eiahe.hr.performance.service.IPerformanceResultService;
import org.eiahe.hr.performance.service.IPerformanceScoreDetailService;
import org.eiahe.hr.performance.listener.PerformanceScoredEventListener;
import org.ehe.common.core.domain.R;
import org.ehe.common.log.annotation.Log;
import org.ehe.common.log.enums.BusinessType;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.system.domain.vo.SysUserVo;
import org.ehe.system.service.ISysUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.dev33.satoken.annotation.SaCheckPermission;

import java.util.List;
import java.util.Objects;

/**
 * 绩效结果Controller
 *
 * @author zhangnn
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/performance/result")
public class PerformanceResultController extends BaseController {

    private final IPerformanceResultService performanceResultService;
    private final IPerformanceScoreDetailService performanceScoreDetailService;
    private final ISysUserService userService;
    private final PerformanceScoredEventListener performanceScoredEventListener;
    private final PerformanceResultMapper performanceResultMapper;
    private final PerformanceScoreDetailMapper performanceScoreDetailMapper;
    private final PerformancePositionIndicatorMapper performancePositionIndicatorMapper;

    /**
     * 查询绩效结果列表
     */
    @SaCheckPermission("performance:result:list")
    @GetMapping("/list")
    public TableDataInfo<PerformanceResultVo> list(PerformanceResultBo result, PageQuery pageQuery) {
        return performanceResultService.queryPageListVo(result, pageQuery);
    }

    /**
     * 获取绩效结果详细信息
     */
    @SaCheckPermission("performance:result:query")
    @GetMapping(value = "/{resultId}")
    public R<PerformanceResultVo> getInfo(@PathVariable("resultId") Long resultId) {
        return R.ok(performanceResultService.queryById(resultId));
    }

    /**
     * 获取绩效结果的评分明细列表
     */
    @SaCheckPermission("performance:result:query")
    @GetMapping("/{resultId}/scoreDetails")
    public R<List<PerformanceScoreDetailVo>> getScoreDetails(@PathVariable("resultId") Long resultId) {
        List<PerformanceScoreDetailVo> list = performanceScoreDetailService.queryListByResultId(resultId);
        // 为每个明细设置评分人姓名
        list.forEach(detail -> {
            SysUserVo sysUserVo = userService.selectUserByUserName(detail.getScorer());
            if (Objects.nonNull(sysUserVo)) {
                detail.setScorerName(sysUserVo.getNickName());
            }
        });
        return R.ok(list);
    }

    /**
     * 新增绩效结果
     */
    @SaCheckPermission("performance:result:add")
    @Log(title = "绩效结果", businessType = BusinessType.INSERT)
    @PostMapping
    public R<Void> add(@Validated @RequestBody PerformanceResultBo result) {
        return toAjax(performanceResultService.insertByBo(result));
    }

    /**
     * 修改绩效结果
     */
    @SaCheckPermission("performance:result:edit")
    @Log(title = "绩效结果", businessType = BusinessType.UPDATE)
    @PutMapping
    public R<Void> edit(@Validated @RequestBody PerformanceResultBo result) {
        return toAjax(performanceResultService.updateByBo(result));
    }

    /**
     * 删除绩效结果
     */
    @SaCheckPermission("performance:result:remove")
    @Log(title = "绩效结果", businessType = BusinessType.DELETE)
    @DeleteMapping("/{resultIds}")
    public R<Void> remove(@PathVariable Long[] resultIds) {
        return toAjax(performanceResultService.deleteWithValidByIds(List.of(resultIds), true));
    }

    /**
     * 确认绩效结果
     */
    @SaCheckPermission("performance:result:confirm")
    @Log(title = "绩效结果", businessType = BusinessType.UPDATE)
    @PutMapping("/confirm/{resultId}")
    public R<Void> confirm(@PathVariable Long resultId) {
        PerformanceResult result = new PerformanceResult();
        result.setResultId(resultId);
        result.setStatus("1");
        PerformanceResultBo resultBo = MapstructUtils.convert(result, PerformanceResultBo.class);
        return toAjax(performanceResultService.updateByBo(resultBo));
    }

    /**
     * 重新生成绩效评分明细
     */
    @SaCheckPermission("performance:result:regenerate")
    @Log(title = "绩效结果", businessType = BusinessType.UPDATE)
    @PostMapping("/regenerate/{resultId}")
    public R<Void> regenerateScoreDetails(@PathVariable Long resultId) {
        PerformanceResultVo resultVo = performanceResultService.queryById(resultId);
        if (resultVo == null) {
            return R.fail("绩效结果不存在");
        }

        try {
            performanceScoredEventListener.generateScoreDetails(
                    resultVo.getEmployeeNo(),
                    resultVo.getCycleId(),
                    resultId);
            return R.ok("绩效评分明细重新生成成功");
        } catch (Exception e) {
            return R.fail("重新生成绩效评分明细失败: " + e.getMessage());
        }
    }

    /**
     * 发布绩效考核计划
     */
    @SaCheckPermission("performance:result:publish")
    @Log(title = "绩效考核计划", businessType = BusinessType.INSERT)
    @PostMapping("/publish")
    public R<Void> publish(@RequestParam String employeeNo,
            @RequestParam Long cycleId,
            @RequestParam Long positionId,
            @RequestParam List<Long> indicatorIds,
            @RequestParam List<String> scorerNos) {
        return toAjax(publishAssessment(employeeNo, cycleId, positionId, indicatorIds, scorerNos));
    }

    /**
     * 发布绩效考核计划
     *
     * @param employeeNo   工号
     * @param cycleId      周期ID
     * @param positionId   岗位ID
     * @param indicatorIds 指标ID列表
     * @param scorerNos    评分人工号列表
     * @return 是否成功
     */
    private Boolean publishAssessment(String employeeNo, Long cycleId, Long positionId,
            List<Long> indicatorIds, List<String> scorerNos) {
        try {
            // 1. 创建或获取绩效结果记录
            Long resultId = createOrGetPerformanceResult(employeeNo, cycleId);

            // 2. 为每个指标和评分人组合生成评分明细记录
            generateScoreDetails(resultId, indicatorIds, scorerNos);

            return true;
        } catch (Exception e) {
            throw new RuntimeException("发布绩效考核计划失败: " + e.getMessage());
        }
    }

    /**
     * 创建或获取绩效结果记录
     *
     * @param employeeNo 工号
     * @param cycleId    周期ID
     * @return 结果ID
     */
    private Long createOrGetPerformanceResult(String employeeNo, Long cycleId) {
        // 查询是否已存在该员工在该周期的绩效结果
        LambdaQueryWrapper<PerformanceResult> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceResult::getEmployeeNo, employeeNo);
        lqw.eq(PerformanceResult::getCycleId, cycleId);
        lqw.eq(PerformanceResult::getDelFlag, "0");
        PerformanceResult existingResult = performanceResultMapper.selectOne(lqw);

        if (existingResult != null) {
            return existingResult.getResultId();
        }

        // 创建新的绩效结果记录
        PerformanceResultBo resultBo = PerformanceResultBo.builder()
                .employeeNo(employeeNo)
                .cycleId(cycleId)
                .totalScore(null)
                .levelId(null)
                .status("0") // 待确认状态
                .build();

        PerformanceResult result = MapstructUtils.convert(resultBo, PerformanceResult.class);
        performanceResultMapper.insert(result);

        return result.getResultId();
    }

    /**
     * 生成评分明细记录
     *
     * @param resultId     结果ID
     * @param indicatorIds 指标ID列表
     * @param scorerNos    评分人工号列表
     */
    private void generateScoreDetails(Long resultId, List<Long> indicatorIds, List<String> scorerNos) {
        // 为每个指标和评分人组合生成评分明细记录
        for (Long indicatorId : indicatorIds) {
            for (String scorerNo : scorerNos) {
                // 检查是否已存在相同的记录
                LambdaQueryWrapper<PerformanceScoreDetail> lqw = Wrappers.lambdaQuery();
                lqw.eq(PerformanceScoreDetail::getResultId, resultId);
                lqw.eq(PerformanceScoreDetail::getIndicatorId, indicatorId);
                lqw.eq(PerformanceScoreDetail::getScorer, scorerNo);
                lqw.eq(PerformanceScoreDetail::getDelFlag, "0");

                if (performanceScoreDetailMapper.selectCount(lqw) == 0) {
                    // 创建新的评分明细记录
                    PerformanceScoreDetail detail = new PerformanceScoreDetail();
                    detail.setResultId(resultId);
                    detail.setIndicatorId(indicatorId);
                    detail.setScorer(scorerNo);
                    detail.setScore(java.math.BigDecimal.ZERO); // 默认分数为0
                    detail.setScoreStatus("0"); // 默认状态为未评分

                    // 获取指标权重（支持层级指标）
                    LambdaQueryWrapper<PerformancePositionIndicator> weightLqw = Wrappers.lambdaQuery();
                    weightLqw.eq(PerformancePositionIndicator::getIndicatorId, indicatorId);
                    weightLqw.eq(PerformancePositionIndicator::getDelFlag, "0");
                    PerformancePositionIndicator weight = performancePositionIndicatorMapper.selectOne(weightLqw);

                    if (weight != null) {
                        detail.setWeight(weight.getWeight());
                    }

                    performanceScoreDetailMapper.insert(detail);
                }
            }
        }
    }
}
